1   /*
2    * Copyright (C) 2012 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect.testing.google;
18  
19  import com.google.common.annotations.GwtCompatible;
20  import com.google.common.collect.BiMap;
21  import com.google.common.collect.testing.DerivedGenerator;
22  import com.google.common.collect.testing.Helpers;
23  import com.google.common.collect.testing.OneSizeTestContainerGenerator;
24  import com.google.common.collect.testing.SampleElements;
25  import com.google.common.collect.testing.TestMapGenerator;
26  import com.google.common.collect.testing.TestSetGenerator;
27  import com.google.common.collect.testing.TestSubjectGenerator;
28  
29  import java.util.ArrayList;
30  import java.util.Collection;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.Map.Entry;
34  import java.util.Set;
35  
36  /**
37   * Derived suite generators for Guava collection interfaces, split out of the suite builders so that
38   * they are available to GWT.
39   *
40   * @author Louis Wasserman
41   */
42  @GwtCompatible
43  public final class DerivedGoogleCollectionGenerators {
44    public static class MapGenerator<K, V> implements TestMapGenerator<K, V>, DerivedGenerator {
45  
46      private final OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> generator;
47  
48      public MapGenerator(
49          OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> oneSizeTestContainerGenerator) {
50        this.generator = oneSizeTestContainerGenerator;
51      }
52  
53      @Override
54      public SampleElements<Map.Entry<K, V>> samples() {
55        return generator.samples();
56      }
57  
58      @Override
59      public Map<K, V> create(Object... elements) {
60        return generator.create(elements);
61      }
62  
63      @Override
64      public Map.Entry<K, V>[] createArray(int length) {
65        return generator.createArray(length);
66      }
67  
68      @Override
69      public Iterable<Map.Entry<K, V>> order(List<Map.Entry<K, V>> insertionOrder) {
70        return generator.order(insertionOrder);
71      }
72  
73      @SuppressWarnings("unchecked")
74      @Override
75      public K[] createKeyArray(int length) {
76        return (K[]) new Object[length];
77      }
78  
79      @SuppressWarnings("unchecked")
80      @Override
81      public V[] createValueArray(int length) {
82        return (V[]) new Object[length];
83      }
84  
85      public TestSubjectGenerator<?> getInnerGenerator() {
86        return generator;
87      }
88    }
89  
90    public static class InverseBiMapGenerator<K, V>
91        implements TestBiMapGenerator<V, K>, DerivedGenerator {
92  
93      private final OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> generator;
94  
95      public InverseBiMapGenerator(
96          OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> oneSizeTestContainerGenerator) {
97        this.generator = oneSizeTestContainerGenerator;
98      }
99  
100     @Override
101     public SampleElements<Map.Entry<V, K>> samples() {
102       SampleElements<Entry<K, V>> samples = generator.samples();
103       return new SampleElements<Map.Entry<V, K>>(reverse(samples.e0), reverse(samples.e1),
104           reverse(samples.e2), reverse(samples.e3), reverse(samples.e4));
105     }
106 
107     private Map.Entry<V, K> reverse(Map.Entry<K, V> entry) {
108       return Helpers.mapEntry(entry.getValue(), entry.getKey());
109     }
110 
111     @SuppressWarnings("unchecked")
112     @Override
113     public BiMap<V, K> create(Object... elements) {
114       Entry<?, ?>[] entries = new Entry<?, ?>[elements.length];
115       for (int i = 0; i < elements.length; i++) {
116         entries[i] = reverse((Entry<K, V>) elements[i]);
117       }
118       return generator.create((Object[]) entries).inverse();
119     }
120 
121     @SuppressWarnings("unchecked")
122     @Override
123     public Map.Entry<V, K>[] createArray(int length) {
124       return new Entry[length];
125     }
126 
127     @Override
128     public Iterable<Entry<V, K>> order(List<Entry<V, K>> insertionOrder) {
129       return insertionOrder;
130     }
131 
132     @SuppressWarnings("unchecked")
133     @Override
134     public V[] createKeyArray(int length) {
135       return (V[]) new Object[length];
136     }
137 
138     @SuppressWarnings("unchecked")
139     @Override
140     public K[] createValueArray(int length) {
141       return (K[]) new Object[length];
142     }
143 
144     public TestSubjectGenerator<?> getInnerGenerator() {
145       return generator;
146     }
147   }
148 
149   public static class BiMapValueSetGenerator<K, V>
150       implements TestSetGenerator<V>, DerivedGenerator {
151     private final OneSizeTestContainerGenerator<BiMap<K, V>, Map.Entry<K, V>>
152         mapGenerator;
153     private final SampleElements<V> samples;
154 
155     public BiMapValueSetGenerator(
156         OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> mapGenerator) {
157       this.mapGenerator = mapGenerator;
158       final SampleElements<Map.Entry<K, V>> mapSamples =
159           this.mapGenerator.samples();
160       this.samples = new SampleElements<V>(
161           mapSamples.e0.getValue(),
162           mapSamples.e1.getValue(),
163           mapSamples.e2.getValue(),
164           mapSamples.e3.getValue(),
165           mapSamples.e4.getValue());
166     }
167 
168     @Override
169     public SampleElements<V> samples() {
170       return samples;
171     }
172 
173     @Override
174     public Set<V> create(Object... elements) {
175       @SuppressWarnings("unchecked")
176       V[] valuesArray = (V[]) elements;
177 
178       // Start with a suitably shaped collection of entries
179       Collection<Map.Entry<K, V>> originalEntries =
180           mapGenerator.getSampleElements(elements.length);
181 
182       // Create a copy of that, with the desired value for each value
183       Collection<Map.Entry<K, V>> entries =
184           new ArrayList<Entry<K, V>>(elements.length);
185       int i = 0;
186       for (Map.Entry<K, V> entry : originalEntries) {
187         entries.add(Helpers.mapEntry(entry.getKey(), valuesArray[i++]));
188       }
189 
190       return mapGenerator.create(entries.toArray()).values();
191     }
192 
193     @Override
194     public V[] createArray(int length) {
195       final V[] vs = ((TestBiMapGenerator<K, V>) mapGenerator.getInnerGenerator())
196           .createValueArray(length);
197       return vs;
198     }
199 
200     @Override
201     public Iterable<V> order(List<V> insertionOrder) {
202       return insertionOrder;
203     }
204 
205     public TestSubjectGenerator<?> getInnerGenerator() {
206       return mapGenerator;
207     }
208   }
209 
210   private DerivedGoogleCollectionGenerators() {}
211 }